package com.henry.chatkit.chat

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.AnimationDrawable
import android.util.AttributeSet
import android.util.Log
import android.view.Gravity
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.henry.chatkit.*
import com.henry.chatkit.input.InputLayout
import com.henry.chatkit.messages.*
import com.henry.chatkit.utils.AudioPlayer
import com.henry.chatkit.utils.BackgroundTasks
import com.henry.chatkit.utils.copyClipboard
import com.henry.chatkit.utils.toast
import com.henry.chatkit.weight.photoview.ImageHelper
import com.henry.chatkit.weight.photoview.PhotoData

open class ChatLayout : ChatLayoutUI {

    private val TAG = this::class.java.simpleName

    private var mVolumeAnim: AnimationDrawable? = null

    private val mAdapter: MessageListAdapter by lazy {
        MessageListAdapter()
    }

    private val mCurrentProvider: MessageProvider by lazy {
        MessageProvider()
    }

    protected var mCallback: ChatLayoutCallback? = null

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    fun initDefault() {
        messageLayout.setMessageAdapter(mAdapter)
        mAdapter.setDataSource(mCurrentProvider)

        // TODO 未做 禁用表情
        inputLayout.disableFace(true)

        initListener()

    }

    private fun initListener() {
        messageLayout.setEmptySpaceClickListener(object : OnEmptySpaceClickListener {
            override fun onClick() {
                Log.d(TAG, "OnEmptySpaceClickListener")

                inputLayout.hideInput()
            }
        })

        messageLayout.setLoadMoreMessageHandler(object : OnLoadMoreHandler {
            override fun loadMore() {
                loadMessages()
            }
        })
        messageLayout.setOnItemClickListener(object : OnItemClickListener {

            override fun onMessageClick(view: View?, position: Int, messageInfo: MessageInfo?) {
                Log.d(TAG, "onMessageClick: $position")

                mCallback?.onMessageClick(view, position, messageInfo)

                if (messageInfo == null) {
                    return
                }

                if (messageInfo.msgType == MessageType.IMAGE) {
                    onClickImage(view, messageInfo)
                } else if (messageInfo.msgType == MessageType.AUDIO) {
                    onClickAudio(view, position, messageInfo)
                }
            }

            override fun onMessageLongClick(view: View?, position: Int, messageInfo: MessageInfo?) {
                Log.d(TAG, "onMessageLongClick: $position")
                mCallback?.onMessageLongClick(view, position, messageInfo)
                // 因为adapter中第一条为加载条目，位置需减1
                messageLayout.showItemPopMenu(position - 1, messageInfo, view)

            }

            override fun onUserIconClick(view: View?, position: Int, messageInfo: MessageInfo?) {
                Log.d(TAG, "onUserIconClick")
                mCallback?.onUserIconClick(view, position, messageInfo)
            }

        })
        messageLayout.setPopActionClickListener(object : OnPopActionClickListener {
            override fun onCopyClick(position: Int, msg: MessageInfo?) {
                copyClipboard(msg?.text)
            }

            override fun onSendMessageClick(msg: MessageInfo?, retry: Boolean) {
                sendMessage(msg, retry)
            }

            override fun onDeleteMessageClick(position: Int, msg: MessageInfo?) {
                deleteMessage(position)
            }

            override fun onRevokeMessageClick(position: Int, msg: MessageInfo?) {
                revokeMessage(position, msg)
            }

        })

        inputLayout.setChatInputHandler(object : InputLayout.ChatInputHandler {
            override fun onInputAreaClick() {
                post { scrollToEnd() }
            }

            override fun onRecordStatusChanged(status: Int) {
                when (status) {
                    InputLayout.ChatInputHandler.RECORD_START -> startRecording()
                    InputLayout.ChatInputHandler.RECORD_STOP -> stopRecording()
                    InputLayout.ChatInputHandler.RECORD_CANCEL -> cancelRecording()
                    InputLayout.ChatInputHandler.RECORD_TOO_SHORT, InputLayout.ChatInputHandler.RECORD_FAILED -> stopAbnormally(
                        status
                    )
                }
            }

        })

        inputLayout.setMessageHandler(object : InputLayout.MessageHandler {
            override fun sendMessage(msg: String?) {
                if (msg == null) {
                    toast("请输入有效文本")
                    return
                }
                val message = MessageExt.buildTextMessage(msg)
                sendMessage(message, false)
            }

            override fun sendAudioMessage(path: String, duration: Int) {
                if (path.isEmpty()) {
                    toast("请录制无效")
                    return
                }
                val message = MessageExt.buildAudioMessage(path, duration)
                sendMessage(message, false)
            }

            override fun sendImageMessage(path: String, width: Int, height: Int) {
                if (path.isEmpty()) {
                    toast("文件不存在")
                    return
                }
                val message = MessageExt.buildImageMessage(path, width, height)
                sendMessage(message, false)
            }

        })
    }

    fun startRecording() {
        post {
            AudioPlayer.instance.stopPlay()
            mRecordingGroup.visibility = VISIBLE
            mRecordingIcon.setImageResource(R.drawable.recording_volume)
            mRecordingTips.setTextColor(Color.WHITE)
            mRecordingTips.text = "手指上滑，取消发送"
            mVolumeAnim = mRecordingIcon.drawable as AnimationDrawable
            mVolumeAnim?.start()
        }
    }

    fun stopRecording() {
        postDelayed({
            mVolumeAnim?.stop()
            mRecordingGroup.visibility = GONE
        }, 500)
    }

    fun cancelRecording() {
        post {
            mRecordingIcon.setImageResource(R.drawable.ic_volume_dialog_cancel)
            mRecordingTips.text = "松开手指，取消发送"
        }
    }

    fun stopAbnormally(status: Int) {
        post {
            mVolumeAnim?.stop()
            mRecordingIcon.setImageResource(R.drawable.ic_volume_dialog_length_short)
            mRecordingTips.setTextColor(Color.WHITE)
            if (status ==  InputLayout.ChatInputHandler.RECORD_TOO_SHORT) {
                mRecordingTips.text = "说话时间太短"
            } else {
                mRecordingTips.text = "录音失败"
            }
        }
        postDelayed({ mRecordingGroup.visibility = GONE }, 1000)
    }

    fun loadMessages() {
        mCallback?.loadMessages()
    }

    fun scrollToEnd() {
        messageLayout.scrollToEnd()
    }

    fun setCallback(callback: ChatLayoutCallback) {
        mCallback = callback
    }

    fun sendMessage(messageInfo: MessageInfo?) {
        if (messageInfo == null || messageInfo.status == MessageStatus.SENDING) {
            return
        }
        mCallback?.sendMessage(messageInfo, false)
    }

    fun sendMessage(messageInfo: MessageInfo?, retry: Boolean) {
        if (messageInfo == null || messageInfo.status == MessageStatus.SENDING) {
            return
        }

        mCallback?.sendMessage(messageInfo, retry)

    }

    fun reloadData(list: List<MessageInfo>) {
        mCurrentProvider.addMessageList(list, true)
    }

    fun addMessageList(list: List<MessageInfo>) {
        mCurrentProvider.addMessageList(list, false)
    }

    fun showMessage(messageInfo: MessageInfo?, retry: Boolean, status: Int = MessageStatus.SENDING) {
        if (messageInfo == null) return

        messageInfo.status = status
        if (status == MessageStatus.SENDING) {
            if (retry) {
                mCurrentProvider.resendMessage(messageInfo)
            } else {
                mCurrentProvider.addMessage(messageInfo)
            }
        } else {
            mCurrentProvider.updateMessage(messageInfo)
        }

    }

    fun updateMessage(messageInfo: MessageInfo) {
        mCurrentProvider.updateMessage(messageInfo)
    }

    fun updateStatus(messageInfo: MessageInfo?, status: Int) {
        if (messageInfo == null) return
        messageInfo.status = status
        mCurrentProvider.updateMessage(messageInfo)
    }

    fun deleteMessage(position: Int) {
        mCurrentProvider.remove(position)
    }

    fun deleteMessage(msg: MessageInfo?) {
        if (msg == null) {
            return
        }
        mCurrentProvider.deleteMessage(msg)
    }

    fun revokeMessage(position: Int, msg: MessageInfo?) {
        // 撤回
        mCallback?.revokeMessage(position, msg)
    }

    fun onClickImage(view: View?, messageInfo: MessageInfo) {

        val data = PhotoData(id = 0, url = messageInfo.path)
        ImageHelper.show(data)
    }

    fun onClickAudio(view: View?, position: Int, messageInfo: MessageInfo) {

        if (view == null) {
            return
        }

        if (AudioPlayer.instance.isPlaying()) {
            AudioPlayer.instance.stopPlay()

            // TODO 相同
            if (AudioPlayer.instance.playerId == messageInfo.id) {
                return
            }
        }

        // 语音已读
        if (!messageInfo.isSelf && !messageInfo.read) {
            messageInfo.read = true

            val itemView = messageLayout.findViewByPosition(position)
            if (itemView != null) {
                val unreadAudioText: TextView = itemView.findViewById(R.id.audio_unread)
                if (!messageInfo.read) {
                    val unreadParams = LayoutParams(40, 20)
                    unreadParams.gravity = Gravity.CENTER_VERTICAL
                    unreadParams.leftMargin = 10
                    unreadAudioText.visibility = View.VISIBLE
                    unreadAudioText.layoutParams = unreadParams
                } else {
                    unreadAudioText.visibility = View.GONE
                }
            }
        }

        val audioPlayImage = view.findViewById<ImageView>(R.id.audio_play_iv)

        if (messageInfo.isSelf) {
            audioPlayImage.setImageResource(R.drawable.message_voice_sender_play)
        } else {
            audioPlayImage.setImageResource(R.drawable.message_voice_receiver_play)
        }

        val animationDrawable = audioPlayImage.drawable as AnimationDrawable

        animationDrawable.start()

        AudioPlayer.instance.startPlay(messageInfo.path, messageInfo.id, object : AudioPlayer.Callback {
            override fun onCompletion(success: Boolean) {
                BackgroundTasks.getInstance()?.runOnUiThread {
                    animationDrawable.stop()
                    if (messageInfo.isSelf) {
                        audioPlayImage.setImageResource(R.drawable.message_voice_sender_normal)
                    } else {
                        audioPlayImage.setImageResource(R.drawable.message_voice_receiver_normal)
                    }
                }
            }

        })

    }

}